<template>
  <div class="chat-view">
    <mt-header fixed :title="chat.chatName">
      <mt-button slot="left" icon="back" @click="$router.go(-1)">返回</mt-button>
      <mt-button v-if="chatType === 1" icon="more" slot="right" @click="handleToGroupInfo"></mt-button>
    </mt-header>
    <div ref="chatContent" class="chat-content" :style="showEmotion || showAddBox ? 'height:calc(75% - 50px);' : 'height:calc(100% - 50px);'" @click.stop="handleHideBox">
      <mt-loadmore :top-method="loadTop" ref="loadmore">
        <div class="message-content" :class="{'is-user': item.userName === user.userName}"
            v-for="(item, i) in messageList" :key="i">
          <img class="message-img" @click.stop="handleToRemarks(item)" :src="`${$url}/${item.avatar}`" alt="">
          <div class="message-wrap" @touchstart="messageTouchS(item)" @touchend="messageTouchE(item)">
            <div v-show="chatType === 1 && item.userName !== user.userName" class="top-name">{{item.remarkName || item.groupNickName || item.userName}}</div>
            <div v-if="item.msgType === 1" class="text-img">
              <img
                class="preview-img"
                v-preview="`${$url}/${item.msgContext}`"
                :preview-title-enable="false"
                :preview-nav-enable="true"
                :src="`${$url}/scale_${item.msgContext}`"
                alt=""
              >
            </div>
            <div v-if="item.msgType === 0" class="message-text">
              <span class="wrapper" v-html="getEmotion(item.msgContext)"></span>
              <div class="arrow"></div>
            </div>
            <div v-if="item.msgType === 3" class="message-text" @click="handlePlay(item.msgContext, item.id, 'audio')">
              <span>{{getTime(item.msgContext)}}</span>
              <i class="iconfont yuyin" :class="item.userName === user.userName ? 'icon-yuyinyou' : 'icon-yuyinzuo'"></i>
              <div class="arrow"></div>
            </div>
            <div v-if="item.msgType === 4" class="message-video" @click="handlePlay(item.msgContext, item.id, 'video')">
              <video class="video" webkit-playsinline="true" x5-playsinline="true" x5-video-orientation="landscape|portrait" controls="controls">
                <source :src="`${$url}/${item.msgContext}`" type="video/mp4">
                your browser does not support the video tag
              </video>
            </div>
          </div>
        </div>
      </mt-loadmore>
    </div>
      <div class="footer-top">
        <i :class="`iconfont ${isKeyboard ? 'icon-jianpan1' : 'icon-yuyin'}`" @click="handleRecorder"></i>
        <template v-if="isKeyboard">
          <Recorder v-if="isApp" :uploadData="uploadData" @file="sendTo(3, $event)"/>
          <Recorder0 v-else :uploadData="uploadData" @file="sendTo(3, $event)"/>
        </template>
        <mt-field
          v-pos_fix
          @keyup.ctrl.enter.native="sendTo(0, text)"
          v-show="!isKeyboard"
          ref="inputVal"
          @focus.native.capture="handleFocus"
          @blur.native.capture="handleBlur"
          v-model="text"
          :disabled="disabledSay === 1 && chatType === 1"
          type="textarea">
        </mt-field>
        <i style="margin: 0 5px;" :class="`iconfont ${showEmotion ? 'icon-jianpan1' : 'icon-xiaolian'}`" @click="handleShowEmotion"></i>
        <i v-show="text" @click="sendTo(0, text)" class="iconfont icon-fasong_l"></i>
        <i v-show="!text" class="iconfont icon-addNew" @click="handleShowAddBox"></i>
      </div>
      <div onselectstart="return false" class="emotion-box" v-show="showEmotion">
          <span class="img" v-for="(value, key, i) in emotionList" :key="i" @click="getText(key)">
            <img :src="require(`../assets/face/${value}.png`)" alt="">
          </span>
      </div>
      <div class="add-box" v-show="showAddBox">
        <div class="add-item" v-for="(item, i) in addList" :key="i" @click="handleClickUploadIndex(i)">
          <input class="upload-photo" v-if="i === 0" type="file" accept="image/*" multiple @change="updateImg($event,1)">
          <input class="upload-photo" v-if="i === 1" type="file" accept="image/*" capture="camera" @change="updateImg($event,1)">
          <input class="upload-photo" v-if="i === 2" type="file" accept="video/*" multiple capture="camcorder" @change="updateImg($event,4)">
          <i :class="`iconfont ${item.icon}`"></i>
          <span>{{item.name}}</span>
        </div>
      </div>
  </div>
</template>
<script>
import emotionList from '@/components/emotion.json'
import { Toast } from 'mint-ui'
import Recorder from '@/components/Recorder'
import Recorder0 from '@/components/Recorder0'
import lrz from 'lrz'
// var hrt = document.documentElement.clientHeight // 获取当前可视区域的高度存到hrt变量
// // 在页面整体加载完毕时
// window.onload = function () {
//   console.warn('fff', document.getElementById('app'))
//   document.getElementById('app').style.height = hrt + 'px' // 把获取到的高度赋值给根div
// }
export default {
  name: 'ChatView',
  components: { Recorder, Recorder0 },
  props: {
    chatType: {
      type: Number, // 1：群聊 0：私聊
      required: true
    },
    chat: {
      type: Object,
      required: true
    }
  },
  data () {
    const user = localStorage.getItem('user')
    const $url = this.$url
    return {
      isUp: false,
      isApp: window.isApp,
      timer: null,
      size: 0,
      user: (user && JSON.parse(user)) || null,
      pageNum: 1,
      messageList: [],
      disabledSay: 0,
      allLoaded: false,
      isKeyboard: false,
      uploadData: {
        uploadUrl: `${$url}/file/upload`
      },
      text: '',
      showAddBox: false,
      showEmotion: false,
      playFlag: true,
      emotionList,
      addList: [
        { key: 'handlePicture', icon: 'icon-picture-fill', name: '照片' },
        { key: 'handleShot', icon: 'icon-paishe_A_Facet', name: '拍摄' },
        { key: 'handleField', icon: 'icon-shipin', name: '视频' },
        // { key: 'handleVoice', icon: 'icon-yuyin1', name: '视频' },
        { key: 'handleSignIn', icon: 'icon-qiandao', name: '签到' }
      ],
      audio: null
    }
  },
  load: {
    dom () {
    },
    plus: () => {
    }
  },
  destroyed () {
    this.stopPlay()
    if (!this.isApp) {
      window.removeEventListener('scroll', this.handleScroll, true)
    }
  },
  mounted () {
    if (this.user === null) {
      this.$router.push('/login')
    }
    if (!this.isApp) {
      window.addEventListener('scroll', this.handleScroll, true)
    }
    // 根据分页获取消息
    this.getMessages()
    // 打开消息
    this.openChat()
    // 主动请求消息
    this.sendTo(0, '', true)
  },
  methods: {
    handleScroll () {
      let scrollTop = Math.floor(document.getElementsByClassName('mint-loadmore')[0].scrollTop)
      if (this.isUpOrDown() && scrollTop <= 0) {
        this.loadMore()
      }
    },
    isUpOrDown () {
      if (/.*Firefox.*/.test(navigator.userAgent)) {
        document.addEventListener('DOMMouseScroll', (e) => {
          e = e || window.event
          this.isUp = e.detail <= 0
        })
      } else {
        document.onmousewheel = (e) => {
          e = e || window.event
          this.isUp = e.wheelDelta > 0
        }
      }
      return this.isUp
    },
    pushMsg (m) {
      if (window.isApp) {
        if (window.plus.os.name === 'Android') {
          if (navigator.userAgent.indexOf('StreamApp') > 0) {
            console.log('当前环境不支持推送')
          } else {
            var options = { cover: false }
            let str = ''
            if (m.msgType === 0) {
              str = m.msgContext
            }
            if (m.msgType === 1) {
              str = '[图片]'
            }
            if (m.msgType === 2) {
              str = '[文件]'
            }
            if (m.msgType === 3) {
              str = '[语音]'
            }
            if (m.msgType === 4) {
              str = '[视频]'
            }
            window.plus.push.createMessage(str, 'LocalMSG', options)
            if (window.plus.os.name === 'iOS') {
              console.log('*如果无法创建消息，请到"设置"->"通知"中配置应用在通知中心显示!')
            }
          }
        }
      }
    },
    handleRecorder () {
      window.scrollTo(0, 0)
      this.isKeyboard = !this.isKeyboard
      if (!this.isKeyboard) {
        this.$nextTick(() => {
          document.getElementsByClassName('mint-field-core')[0].focus()
        })
      }
    },
    handleFocus () {
      this.showAddBox = false
      this.showEmotion = false
    },
    handleBlur () {
      // if (this.showAddBox || this.showEmotion) {
      //   return
      // }
      // window.scrollTo(0, 0)
    },
    getNewMessage () {
      let id = 0
      if (this.messageList !== undefined) {
        id = this.messageList[this.messageList.length - 1].id
      }
      this.$socket.getLastMessage(id, this.chat.chatId, this.user.id, this.chatType, res => {
        if (res.success) {
          if (this.chatType === 1) {
            this.responLastMessage(res.groupMsgList)
          } else if (this.chatType === 0) {
            this.responLastMessage(res.friendMsgList)
          } else {
            console.warn(res)
          }
        }
      })
    },
    responLastMessage (msg) {
      msg.forEach(m => {
        if (!this.messageList.map(v => v.id).includes(m.id)) {
          this.messageList.push(m)
          if (m.sendUid === this.user.id) {
            this.scrollToBottom()
          }
          // 给手机消息中心推送消息
          this.pushMsg(m)
        }
      })
      this.messageList.sort((a, b) => { return a.id - b.id })
    },
    playRecord (url) {
      if (this.playFlag) {
        this.playFlag = false
        this.audio = window.plus.audio.createPlayer(url)
        console.log(this.audio)
        this.audio.play(() => {
          this.stopPlay()
          this.playFlag = true
        }, function (e) {
          console.log('播放音频文件"' + url + '"失败：' + e.message)
        })
      } else {
        this.stopPlay()
        this.playFlag = true
      }
    },
    stopPlay () {
      if (this.audio) {
        this.audio.stop()
        this.audio = null
      }
    },
    handleToGroupInfo () {
      this.$router.push('/groupInfo')
    },
    getMessages () {
      this.pageNum = 1
      const str = this.chatType === 1 ? 'getGroupMessages' : 'getFriendMessages'
      this.$socket[str](this.chat.chatId, this.user.id, this.pageNum, (res) => {
        this.messageList = res.messageList
      })
    },
    openChat () {
      this.$socket.openChat(this.chat.chatId, this.user.id, this.chatType, res => {
        if (res.success) {
          if (this.chatType === 1) {
            this.disabledSay = res.groupUser.status
          }
        }
      })
    },
    handleToRemarks (item) {
      localStorage.setItem('userItem', JSON.stringify(item))
      this.$router.push('/remarks')
    },
    messageTouchS (item) {
      if (this.user.userName === item.userName) {
        this.timer = setTimeout(() => {
          let t = ((new Date()).getTime() - item.operTime) / 60000
          if (t <= 2) {
            this.$messagebox.confirm('是否撤回消息').then(action => {
              let del = this.chatType === 0 ? 'deleteFriendMsg' : 'deleteGroupMsg'
              this.$socket[del](this.user.id, item.id, res => {
                this.sendTo(6, '撤销')
              })
            }, cancel => {
              console.log(cancel + 'cancel')
            })
          } else {
            Toast('该消息已超过时间限制，无法撤销')
          }
        }, 1000)
      }
    },
    messageTouchE () {
      window.clearTimeout(this.timer)
      this.timer = null
    },
    // 播放时间
    getTime (msgContext) {
      const { time } = JSON.parse(msgContext)
      return `${time}'' `
    },
    handlePlay (msgContext, id, type) {
      const { url } = JSON.parse(msgContext)
      if (window.isApp) {
        this.playRecord(`${this.$url}/${url}`)
      } else {
        let flag = true
        let medias = document.getElementsByTagName(type)
        for (const key in medias) {
          if (medias[key].paused === false) {
            medias[key].pause()
          }
          if (medias[key].id - 0 === id) {
            medias[key].currentTime = 0
            medias[key].play()
            flag = false
          }
        }
        if (flag) {
          const media = document.createElement(type)
          media.src = `${this.$url}/${url}`
          media.id = id
          document.body.appendChild(media)
          media.play().then()
        }
      }
    },
    // 点击空白部分隐藏下面输入
    handleHideBox () {
      this.showEmotion = false
      this.showAddBox = false
      window.scrollTo(0, 0)
    },
    // 滚动条滚动到底部
    scrollToBottom () {
      this.$nextTick(() => {
        let div = this.$refs.loadmore.$el
        div.scrollTop = div.scrollHeight
      })
    },
    getEmotion (msg) {
      msg = msg.replace(/\[.+?\]/g, (a, b) => {
        let index = this.emotionList[a]
        if (!index) {
          return a
        } else {
          let url = require(`../assets/face/${index}.png`)
          return `<img class="emotion-img" src=${url} alt="" />`
        }
      })
      return msg
    },
    // 处理加号里面的各种事件
    handleClickUploadIndex (i) {
      // 签到
      if (i === 3) {
        this.sendTo(5, '签到')
      }
    },
    // 单文件上传
    updateImg (el, type) {
      if (!el.target.files[0].size) return
      this.filesList(el.target.files, type)
    },
    // 遍历图片列表
    filesList (files, type) {
      [...files].forEach((v) => this.fileAdd(v, type))
    },
    // 添加到渲染列表
    fileAdd (file, type) {
      this.size += file.size
      this.postData(file, type)
    },
    postData (file, type) {
      let index = file.name.lastIndexOf('.')
      let suffix = file.name.substr(index)
      console.log(suffix)
      if (type === 4 || suffix === '.gif' || suffix === '.GIF') {
        let formData = new FormData()
        formData.append('file', file)
        this.$axios.post(this.uploadData.uploadUrl, formData).then((res) => {
          if (res.data.success) {
            this.sendTo(type, res.data.data)
          }
        }).catch((error) => {
          console.log(error)
        })
      } else {
        lrz(file, {
          width: 400,
          quality: 0.8
        }).then((rst) => {
          console.log(rst)
          // 成功时执行
          let formData = new FormData()
          formData.append('file', rst.file, rst.origin.name)
          this.$axios.post(this.uploadData.uploadUrl, formData).then((res) => {
            if (res.data.success) {
              this.sendTo(type, res.data.data)
            }
          }).catch((error) => {
            console.log(error)
          })
        }).catch((error) => {
          console.log(error)
        }).always(function () {
          // 不管成功或失败，都会执行
        })
      }
    },
    response (res) {
      res.messageList.forEach(m => {
        if (!this.messageList.map(v => v.id).includes(m.id)) {
          this.messageList.push(m)
        }
      })
      this.messageList.sort((a, b) => { return a.id - b.id })
    },
    loadMore () {
      this.pageNum = this.pageNum + 1
      let str = this.chatType === 1 ? 'getGroupMessages' : 'getFriendMessages'
      this.$socket[str](this.chat.chatId, this.user.id, this.pageNum, res => {
        this.response(res)
      })
    },
    loadTop () {
      this.loadMore()
      this.$refs.loadmore.onTopLoaded()
    },
    handleShowAddBox () {
      window.scrollTo(0, 0)
      this.isKeyboard = false
      this.showEmotion = false
      this.showAddBox = !this.showAddBox
      this.scrollToBottom()
    },
    handleShowEmotion () {
      window.scrollTo(0, 0)
      this.isKeyboard = false
      this.showAddBox = false
      this.showEmotion = !this.showEmotion
      this.scrollToBottom()
      if (!this.showEmotion) {
        document.getElementsByClassName('mint-field-core')[0].focus()
      }
    },
    getText (key) {
      this.text = `${this.text}${key}`
    },
    responseMessage (res, msgType) {
      if (res.success) {
        this.getNewMessage()
        if (msgType === 5) {
          localStorage.setItem('user', JSON.stringify(res.iUser))
          Toast('签到成功')
        }
      } else {
        if (msgType === 5) {
          Toast('今天已经签到')
        }
      }
    },
    sendTo (msgType, text, stop) {
      let flag = this.chatType === 1
      if (flag && this.disabledSay === 1) {
        Toast('你已经被禁言')
        return false
      }
      let str = flag ? 'sendToGroup' : 'sendToFriend'
      console.log(this.chat)
      this.$socket[str](this.chat.chatId, this.user.id, text || '', msgType, res => {
        if (res.messageList === undefined) {
          this.responseMessage(res, msgType)
        } else {
          this.messageList = res.messageList
        }
      })
      this.openChat()
      this.text = ''
      if (this.showAddBox || this.showEmotion || stop) {
        return
      }
      document.getElementsByClassName('mint-field-core')[0].focus()
    }
  }
}
</script>
<style lang="less">
  .chat-view {
    .top-name {
      color: #999;
      text-align: left;
    }
    .message-wrap {
      & > div:active {
        background: #9EEA6A;
      }
    }
    .emotion-img {
      width: 24px;
      height: 24px;
    }
    .message-video {
      .video {
        border-radius: 4px;
        width: 150px;
        background: #000;
      }
    }
    .chat-content {
      width: 100%;
      overflow: hidden;
      background: #fff;
      .mint-loadmore {
        height: 100%;
        overflow-x: hidden;
        overflow-y: auto;
      }
      .message-content {
        display: flex;
        margin-top: 10px;
      }
      .text-img {
        .preview-img {
          width: 150px;
          border-radius: 4px;
        }
      }
      .message-text {
        position: relative;
        border-radius: 4px;
        max-width: 240px;
        min-width: 27px;
        min-height: 30px;
        background: #9EEA6A;
        font-size: 14px;
        color: #000;
        padding: 8px 10px;
        text-align: left;
        display: inline-table;
        span {
          word-break: break-all;
        }
        .arrow {
          width: 10px;
          height: 10px;
          background: #9EEA6A;
          position: absolute;
          left: -2px;
          top: 10px;
          transform: rotate(45deg);
        }
        .wrapper{
          white-space: pre-wrap;
        }
      }
      .message-img {
        margin: 0 10px;
        width: 45px;
        height: 45px;
        border-radius: 50%;
      }
      .is-user {
        justify-content: flex-start;
        flex-direction: row-reverse;
        .message-text {
          background: #26a2ff;
          color: #fff;
        }
        .arrow {
          background: #26a2ff;
          right: -2px;
          left: initial;
        }
      }
    }
    .add-box {
        height: 25%;
        overflow-x: hidden;
        overflow-y: auto;
        background: #f5f5f5;
        .add-item {
          width: 25%;
          margin-top: 10px;
          float: left;
          display: flex;
          flex-direction: column;
          justify-content: center;
          align-items: center;
          position: relative;
          .upload-photo {
            position: absolute;
            opacity: 0;
            width: 60px;
            height: 60px;
            top: 0;
          }
          i {
            font-size: 24px;
            padding: 17px 18px;
            background: #fff;
            border-radius: 4px;
          }
          span {
            margin-top: 2px;
            color: #949494;
          }
        }
      }
      .emotion-box {
        height: 25%;
        box-sizing: border-box;
        overflow-x: hidden;
        overflow-y: auto;
        width: 100%;
        background: #f5f5f5;
        .img {
          width: 10%;
          height: 40px;
          display: flex;
          align-items: center;
          justify-content: center;
          float: left;
          img {
            width: 24px;
            height: 24px;
            border: none;
          }
        }
      }
      .footer-top {
        background: #f5f5f5;
        padding: 0 10px;
        height: 50px;
        display: flex;
        align-items: center;
        justify-content: space-between;
        .send-btn {
          height: 30px;
          width: 40px;
          background: #26a2ff;
          color: #fff;
          text-align: center;
          line-height: 30px;
          border-radius: 4px;
        }
        .mint-field {
          height: 60%;
          width: 72%;
          border-radius: 4px;
          .mint-cell-wrapper {
            padding: 0 5px;
            background-image: none;
          }
        }
        .iconfont {
          font-size: 24px;
        }
      }
      .mint-cell {
        min-height: initial;
        .mint-cell-value {
          padding: 0;
        }
        div, .mint-field-core {
          height: 100%;
        }
        .mint-field-core {
          font-size: 13px;
          overflow: hidden;
          height: 70%;
          resize: none;
          padding: 0;
        }
        .mint-field-clear {
          display: flex;
          align-items: center;
        }
      }
  }
</style>
